﻿Imports System.ComponentModel
Imports LibraryFiles


Class MainWindow
    Implements INotifyPropertyChanged

    Private _mru As New MostRecentFiles
    Private _comic As Comic
    Private _rl As ReadingList
    Protected WithEvents FileOpener As BackgroundWorker

    Public ReadOnly Property MRU As MostRecentFiles
        Get
            Return _mru
        End Get
    End Property

    Public ReadOnly Property Pages As ComicPages
        Get
            If _comic Is Nothing Then
                Return New ComicPages
            Else
                Return _comic.ComicPages
            End If
        End Get
    End Property

    Public Property DisplayUpdate As Boolean

    Protected Sub ElementRefreshes()
        OnPropertyChanged("Pages")
        OnPropertyChanged("DisplayUpdate")
    End Sub

    Protected Sub RunOpenCommand()
        '     monitor.TrackFeature("OpenFile.Standard")
        Me.Cursor = Cursors.Wait
        Dim f As New Windows.Forms.OpenFileDialog
        f.Multiselect = False
        f.Filter = "All Files (*.*)|*.*|Comic Book Archives (*.cbr, *.cbz, *.cb7, *.rar, *.zip)|*.cbr;*.cbz;*.cb7;*.rar;*.zip|Graphic Novel Archives (*.gnr, *.gnz)|*.gnr;*.gnz|Comic Book PDF (*.pdf)|*.pdf"
        f.FilterIndex = 1
        Dim dlg As Windows.Forms.DialogResult = f.ShowDialog
        If dlg = Forms.DialogResult.OK Then
            If FileOpener.IsBusy Then FileOpener.CancelAsync()
            If Not _comic Is Nothing Then _comic.Dispose()
            If Not _rl Is Nothing Then _rl.Dispose()
            '       My.Settings.LastFileStoppedPage = 0
            FileOpener.RunWorkerAsync(f.FileName)
        Else
            Me.Cursor = Cursors.Arrow
        End If ' dlg = Forms.DialogResult.OK 
    End Sub

    Protected Sub RunOpenDirCommand()
        Me.Cursor = Cursors.Wait
        Dim f As New Windows.Forms.FolderBrowserDialog
        f.Description = "Select the folder to be opened inside of eComic"
        Dim dlg As Windows.Forms.DialogResult = f.ShowDialog
        If dlg = Forms.DialogResult.OK Then
            If FileOpener.IsBusy Then FileOpener.CancelAsync()
            If Not _comic Is Nothing Then _comic.Dispose() : _comic = Nothing
            If Not _rl Is Nothing Then _rl.Dispose() : _rl = Nothing
            '    My.Settings.LastFileStoppedPage = 0
            FileOpener.RunWorkerAsync(f.SelectedPath)
        Else
            Me.Cursor = Cursors.Arrow
        End If
    End Sub

    Public Sub LoadFileFromCommandLine(ByVal fileName As String)
        '   monitor.TrackFeature("OpenFile.CommandLine")
        If IO.File.Exists(fileName) Then FileOpener.RunWorkerAsync(fileName)
    End Sub ' LoadFileFromCommandLine 


     


#Region "Event Items"
    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Public Overloads Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

#End Region

#Region "File Opener Background Worker"
    Private Sub FileOpener_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles FileOpener.DoWork
        Try
            Dim fileName As String = e.Argument.ToString
            Dim comic As Comic
            Dim rl As ReadingList

            Dim ext As String = IO.Path.GetExtension(fileName)
            If ext.Contains("gn") Then
                ' TODO : Implement Reading List 
                e.Cancel = True
                Exit Sub
                'bw.rl = New readingList(bw.fileName)
                'If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
                'bw.comic = New Comic(_rl.getFileByIndex(0))
                'If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
            Else ' ext.Contains("gn") 
                comic = New Comic(fileName)
                If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub

                rl = New ReadingList(fileName)
                If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub

            End If ' ext.Contains("gn") 

            FileOpener.ReportProgress(1, rl)
            FileOpener.ReportProgress(2, comic)

            Dim fileList As New List(Of String)
            Select Case comic.ArchiveType
                Case ArchiveType.CBR
                    If Not IO.Directory.Exists(comic.TempFolder) Then IO.Directory.CreateDirectory(comic.TempFolder)
                    Dim d As New unRar.Decompressor(comic.Path)
                    Dim b As Boolean = True
                    Dim x As Integer = d.RARFiles.Count
                    FileOpener.ReportProgress(5, x)
                    For Each rarentry In d.RARFiles
                        b = d.UnPack(rarentry.Filename, comic.TempFolder)
                        If FileChecker.CheckImageFileName(rarentry.FileName) Then fileList.Add(comic.TempFolder & "\" & rarentry.filename)
                        If Not b Then
                            e.Cancel = True
                            e.Result = "CBR File Failed to Decompress."
                            Exit Sub
                        End If ' Not b = True 
                        If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub
                        FileOpener.ReportProgress(6, x)
                    Next

                Case ArchiveType.CBZ

                    Using zip1 As Ionic.Zip.ZipFile = Ionic.Zip.ZipFile.Read(comic.Path)
                        Dim zipItem As Ionic.Zip.ZipEntry
                        Dim x As Integer = zip1.Count
                        FileOpener.ReportProgress(5, x)
                        For Each zipItem In zip1
                            zipItem.Extract(comic.TempFolder, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
                            If FileChecker.CheckImageFileName(zipItem.FileName) Then fileList.Add(comic.TempFolder & "/" & zipItem.FileName)
                            If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub
                            FileOpener.ReportProgress(6, x)
                        Next
                    End Using

                Case ArchiveType.PDF
                    If Not IO.Directory.Exists(comic.TempFolder) Then IO.Directory.CreateDirectory(comic.TempFolder)
                    Dim pdfDoc As PdfSharp.Pdf.PdfDocument = PdfSharp.Pdf.IO.PdfReader.Open(comic.Path)
                    Dim counter As Integer = 1
                    For Each Page As PdfSharp.Pdf.PdfPage In pdfDoc.Pages
                        Dim resources As PdfSharp.Pdf.PdfDictionary = Page.Elements.GetDictionary("/Resources")
                        If Not resources Is Nothing Then
                            Dim xObjects As PdfSharp.Pdf.PdfDictionary = resources.Elements.GetDictionary("/XObject")
                            If Not xObjects Is Nothing Then
                                Dim items As ICollection(Of PdfSharp.Pdf.PdfItem) = xObjects.Elements.Values
                                For Each pdfItem As PdfSharp.Pdf.PdfItem In items
                                    Dim reference As PdfSharp.Pdf.Advanced.PdfReference = CType(pdfItem, PdfSharp.Pdf.Advanced.PdfReference)
                                    If Not reference Is Nothing Then
                                        Dim xObject As PdfSharp.Pdf.PdfDictionary = CType(reference.Value, PdfSharp.Pdf.PdfDictionary)
                                        ' Ensure the Object is an external Object and an image 
                                        If Not xObject Is Nothing AndAlso String.Compare(xObject.Elements.GetString("/Subtype"), "/Image") = 0 Then
                                            Dim filter As String = xObject.Elements.GetName("/Filter")
                                            Select Case filter
                                                Case "/DCTDecode"
                                                    counter += 1
                                                    Dim stream As Byte() = xObject.Stream.Value
                                                    Dim fName As String = comic.TempFolder & "/" & String.Format("page{0}.jpg", counter.ToString("0000"))
                                                    Dim fs As New System.IO.FileStream(fName, System.IO.FileMode.Create, System.IO.FileAccess.Write)
                                                    Dim bw As New System.IO.BinaryWriter(fs)
                                                    bw.Write(stream)
                                                    bw.Flush()
                                                    bw.Close()
                                                    fs.Close()
                                                    fs.Dispose()
                                                    bw = Nothing
                                                    fs = Nothing
                                                    fileList.Add(fName)
                                                Case "/FlateDecode"
                                                Case Else
                                                    ' Do Nothing 
                                            End Select
                                        End If ' Not xObject Is Nothing 
                                    End If ' Not reference Is Nothing 
                                Next
                            End If
                        End If
                    Next ' Page In pdfDoc.Pages 
                    If counter = 0 OrElse fileList.Count = 0 Then
                        e.Cancel = True
                        e.Result = "Unable to process PDF file."
                        Exit Sub
                    End If

                Case ArchiveType.OpenDirectory
                    Dim x As Integer = IO.Directory.GetFiles(comic.Path).Count
                    FileOpener.ReportProgress(5, x)
                    For Each fn As String In IO.Directory.GetFiles(comic.Path)
                        If FileChecker.CheckImageFileName(fn) Then fileList.Add(fn)
                        If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub
                        FileOpener.ReportProgress(6, x)
                    Next
                Case Else
                    e.Cancel = True : Exit Sub
            End Select

            fileList.Sort()
            For Each s As String In fileList
                Dim x As New comicPage(s)
                FileOpener.ReportProgress(3, x)
                If FileOpener.CancellationPending Then e.Cancel = True : e.Result = String.Empty : Exit Sub
            Next ' Each String In fileList 

            e.Result = fileName
        Catch ex As Exception
            Debug.WriteLine(ex.ToString)
            FileOpener.ReportProgress(-1, ex)
            e.Cancel = True
            e.Result = ex
        End Try
    End Sub ' FileOpener_DoWork 

    Private Sub FileOpener_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles FileOpener.ProgressChanged
        Select Case e.ProgressPercentage
            Case 1 ' Set Reading List 
                Me._rl = e.UserState
                Me.prgLoading.Value = 0
            Case 2 ' Set Comic 
                Me.prgLoading.Value = 0
                If Not Me._comic Is Nothing Then Me._comic.Dispose()
                Me._comic = e.UserState
                OnPropertyChanged("Pages")
                'lstPages.ItemsSource = _comic.ComicPages
                'Me.lstPageNames.ItemsSource = _comic.ComicPages
                'Me.lstPagesBottom.ItemsSource = _comic.ComicPages
                '  lstPages.SelectedIndex = 0
            Case 5
                Me.prgLoading.Value = 0
                Me.prgLoading.Maximum = e.UserState
                Me.prgLoading.Value = 0
            Case 6
                Me.prgLoading.Value = Me.prgLoading.Value + 1
            Case -1
                Dim ex As Exception = e.UserState
                Debug.WriteLine(ex.ToString)
                MsgBox("There was an error opening the selected file.", MsgBoxStyle.Critical, "eComic - File Open Error")
            Case Else
                Me._comic.ComicPages.Add(CType(e.UserState, comicPage))
                OnPropertyChanged("Pages")
                Me.lsvImages.Items.Refresh()
                '  lstPages.Items.Refresh()
                '  Me.lstPageNames.Items.Refresh()
                ' If Me._comic.ComicPages.Count = 1 Then lstPages.SelectedIndex = 0
                Me.prgLoading.Value = Me.prgLoading.Value + 1
        End Select ' Case e.ProgressPercentage 
    End Sub ' FileOpener_ProgressChanged 

    Private Sub FileOpener_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles FileOpener.RunWorkerCompleted
        Me.Cursor = Cursors.Arrow
        Me.prgLoading.Value = 0
        If e.Cancelled Then
            '    If Not e.Result.GetType Is GetType(Exception) Then
            If Not Me._comic Is Nothing Then Me._comic.Dispose() : Me._comic = Nothing
            If Not Me._rl Is Nothing Then Me._rl.Dispose() : Me._rl = Nothing

            If String.IsNullOrEmpty(e.Result) Then
                MsgBox("Open File Request Was Cancelled.", MsgBoxStyle.Information)
            Else
                MsgBox(e.Result, MsgBoxStyle.Information)
            End If
            Me.Cursor = Cursors.Arrow
            Exit Sub
            'End If
        End If ' e.Cancelled 
        Dim fn As String = e.Result
        'My.Settings.LastFileOpened = fn
        If _comic.ArchiveType <> ArchiveType.OpenDirectory Then Me.MRU.Append(New MostRecentFile(fn, True, 0))
        Me.mruList.Items.Refresh()
        OnPropertyChanged("Pages")
        Me.lsvImages.Items.Refresh()
        'Me.lstPages.SelectedIndex = _resumeReadingVal
        '_resumeReadingVal = 0
        'Me.sldPageNmbers.Maximum = Me.PageCount
        'Me.sldPageNmbers.Value = Me.lstPages.SelectedIndex
        Debug.WriteLine("Pages: " & _comic.ComicPages.Count)
        Me.DataContext = Me
        'Debug.WriteLine("Pages In Lisbox: " & lstPages.Items.Count)
        Me.ElementRefreshes()
        Me.Cursor = Cursors.Arrow
    End Sub

#End Region

#Region "Opening File Commands"
  

    Private Sub OpenCommand_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        RunOpenCommand()
    End Sub

    Private Sub mruList_MostRecentFileSelected(ByVal sender As System.Object, ByVal e As Microsoft.Windows.Controls.Ribbon.MostRecentFileSelectedEventArgs)
        Dim fn As String = CType(e.SelectedItem, MostRecentFile).FilePath
        If Len(Trim(fn)) > 0 AndAlso IO.File.Exists(fn) Then
            If Me.FileOpener.IsBusy Then Me.FileOpener.CancelAsync()
            Me.Cursor = Cursors.Wait
            FileOpener.RunWorkerAsync(fn)
        Else ' Len(Trim(fn)) > 0 AndAlso IO.File.Exists(fn) 
            MsgBox("The selected file does not exist.", MsgBoxStyle.Information, "eComic")
        End If ' Len(Trim(fn)) > 0 AndAlso IO.File.Exists(fn) 
    End Sub

    Private Sub OpenDirCommand_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        RunOpenDirCommand()
    End Sub

#End Region


    Private Sub Savecommand_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
        e.CanExecute = True
    End Sub

    Private Sub Savecommand_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        MsgBox("Not Implemented")
    End Sub


    Private Sub OptionsCommand_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        MsgBox("Not Implemented")
    End Sub


    Private Sub ExitApplicationCommand_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        ' TODO : Add Comic Clean-Up Functionality Here 
        Me.Close()
    End Sub

    Private Sub eComicEditor_Initialized(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Me.Resources.MergedDictionaries.Add(Microsoft.Windows.Controls.Ribbon.PopularApplicationSkins.Office2007Silver)
        Me.DataContext = Me

        FileOpener = New BackgroundWorker
        FileOpener.WorkerReportsProgress = True
        FileOpener.WorkerSupportsCancellation = True

        Dim file_name As String
        For i As Integer = 1 To 15
            file_name = GetSetting("eComicEditor", "MruList", "FileName" & i, "")
            If file_name.Length > 0 AndAlso IO.File.Exists(file_name) Then
                MRU.Append(New MostRecentFile(file_name, True))
            End If ' file_name.Length > 0 
        Next ' i = 1 To 15 
        Me.mruList.ItemsSource = _mru
        Me.mruList.Items.Refresh()
         
    End Sub



    Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

    End Sub

End Class
